package sysRecomd;

import java.util.Collections;
import java.util.List;

import donnee.Revue;
import donnee.VecteurCreux;

public abstract class ClassificationRevue {

	public VecteurCreux teta;

	public ClassificationRevue() {
		this.teta = new VecteurCreux();
	}

	protected abstract double gradient(double f, double y);

	protected abstract double cout(double f, double y);

	public void iterationApprentissage(List<Revue> revues, List<Revue> ens_test, int index, double epsilon, double diffLimit, int etape) {
		double p = performance(revues, index);
		double np;
		double diff = 0L;
		int i = 0;
		do {
			apprentissage(revues, epsilon, index);
			np = performance(revues, index);
			diff = Math.abs(p - np);
			p = np;
			//System.out.println("np " + np + " " + performance(ens_test, index));
			if (diff < diffLimit)
				i++;
			else
				i = 0;
		} while (i < etape);
	}

	public double performance(List<Revue> revues, int index) {
		double cout = 0L;
		for (Revue r : revues)
			cout = cout + cout(f(r), r.getNote()[index]);
		return cout / revues.size();
	}

	public void apprentissage(List<Revue> revues, double epsilon, int index) {
		Collections.shuffle(revues);

		for (Revue r : revues) {
			double f = f(r);
			double gradient = gradient(f, r.getNote()[index]);
			for (int i : r.getContent()) {
				teta.getVecteur()[i] = teta.getVecteur()[i] - epsilon * gradient;
			}
		}
	}

	public double f(Revue r) {
		double f = 0L;
		for (int i : r.getContent())
			f = f + teta.getVecteur()[i];
		return f;
	}

}
